package com.groupbuying.payconsumer.mq;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.com.alibaba.fastjson.serializer.SerializerFeature;
import com.groupbuying.payconsumer.connector.OrderFeign;
import com.groupbuying.payconsumer.constants.CurrencyPayConstans;
import com.groupbuying.payconsumer.constants.PayInfoEnumConstants;
import com.groupbuying.payconsumer.domain.PayInfoDO;
import com.groupbuying.payconsumer.domain.PayOrderRelDO;
import com.groupbuying.payconsumer.service.PayCurpayResultService;
import com.groupbuying.payconsumer.service.PayInfoService;
import com.groupbuying.payconsumer.service.PayOrderRelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付中心积分消费回执消费监听
 *
 * @Author lisurilige
 * @Date 2019-09-09
 */
@Component
public class CurrencyPayResult  {
    public static final Logger LOGGER = LoggerFactory.getLogger(CurrencyPayResult.class);
    @Autowired
    private PayCurpayResultService curpayResultService;
    @Autowired
    private PayInfoService payInfoService;
    @Autowired
    private PayOrderRelService payOrderRelService;
    @Autowired
    private Producer producer;
    @Autowired
    private OrderFeign orderFeign;

    @Value("${Commodity_Order_Config.counterId}")
    private String counterId;

    @Transactional(rollbackFor = Exception.class)
    public boolean dealResult(Map<String,Object> messageBody) {

        String baseLog = "支付中心,积分支付回执信息处理,";

        LOGGER.error("{}===>打印接收数据:{}",baseLog,messageBody);

        //1. 解析回传参数
        //返回参数 balanceCode、message、prepayNo、payMoney、customerUuid、orderNum、registBusNum
        String curState = messageBody.get("currencyCode") == null?null : messageBody.get("currencyCode").toString();
        String message = messageBody.get("message") == null?null : messageBody.get("message").toString();
        String payCur = messageBody.get("payCurrency") == null?null : messageBody.get("payCurrency").toString();
        String orderNum = messageBody.get("orderNum") == null?null : messageBody.get("orderNum").toString();

        //2. 检查回传参数

        //3. 保存积分支付回执消息
        //TODO 因为是自己系统数据所以不需要保存

        //4. 获取支付单信息
        //获取支付单与订单关联信息
        PayOrderRelDO payOrderRelDO = payOrderRelService.getByOutTradeNo(orderNum);
        //获取支付单信息
        PayInfoDO payInfoDO = payInfoService.get(payOrderRelDO.getId());

        //5.验证本地信息  与  回传数据是否合法
        if (payInfoDO == null){
            LOGGER.error("{}没有查询到支付单信息,第三方支付id:{}", baseLog,orderNum);
            return true;
        }

        // 回执积分与支付单积分不一致
        if (payInfoDO.getPayCur().compareTo(new BigDecimal(payCur)) != 0) {
            //TODO 金额不一致对应的处理（作为异常订单处理），暂时记录日志，然后标记消费
            //TODO 发送订单中心冻结交（或许）
            LOGGER.error("{}支付单积分与回执积分不相等,第三方支付id:{},code:{},支付单积分:{},回执积分:{}",
                    baseLog);
            return true;
        }

        //6.判断单据是否成功在进行相应操作单据
        //积分支付失败
        if (!CurrencyPayConstans.CURRENCY_PAY_SYN_RESULT_SUCCESS.equals(curState)) {
            //TODO  先做不是失败不是成功处理
//            if (!PayInfoEnumConstants.ENUM_PAYSTATE_FAILPAY.equals(payInfoDO.getPayState())) {
//                //强行修改支付单的支付状态为支付失败
//                payInfoDO.setPayState(PayInfoEnumConstants.ENUM_PAYSTATE_FAILPAY);
//                payInfoDO.setGmtModified(new Date());
//                payInfoService.update(payInfoDO);
//            }
            //TODO 交易失败的各种处理，如果已经是成功的状态怎么办？
            //TODO 需要发送到订单中心，修改订单的状态
            LOGGER.error("{}积分支付不成功,不需要通知其他中心,直接退出,第三方支付id:{},code:{},支付单积分:{},回执积分:{}",
                    baseLog,orderNum,curState,payInfoDO.getPayCur(),payCur);
            return true;
        }

        //订单状态是支付成功
        if (PayInfoEnumConstants.ENUM_PAYSTATE_SUCPAY.equals(payInfoDO.getPayState())) {
            //这个返回代表不往其他中心发消息
            LOGGER.info("{}支付单已经是成功状态,所以不需要通知发送其他中心,第三方支付id:{},code:{},积分:{}",
                    baseLog,orderNum,curState,payCur);
            return true;
        }
        payInfoDO.setPayState(PayInfoEnumConstants.ENUM_PAYSTATE_SUCPAY);
        payInfoDO.setGmtModified(new Date());
        payInfoService.update(payInfoDO);

        String orderchannel = payOrderRelDO.getOrderId().substring(4,7);

        //打印日志公共
        StringBuilder logBuilder = new StringBuilder();
        logBuilder.append(baseLog).append("第三方支付id:").append(orderNum)
                .append(",code:").append(curState).append(",积分:").append(payCur);

        //订单中心
        Map<String, Object> orderParam = new HashMap<>();
        //设置分账中心消息传递内容
        Map<String, Object> settleParam = new HashMap<>();

        //TODO 需要修改需要的参数
        //查询那个订单
        if ("002".equals(orderchannel)) {
            LOGGER.info("{}商品订单发送订单、分账",baseLog);
            //获取商品订单信息
            Map<String,?> orderMap = orderFeign.getCommodityOrderForPay(payOrderRelDO.getOrderId());

            if (orderMap == null){
                LOGGER.error("{}商品订单订order查询fegin查询为空",baseLog);
                return false;
            }
            //设置订单中心消息传递内容
            orderParam.put("id", orderMap.get("id"));
            orderParam.put("payAmount",payCur);

            //查询那个订单
            settleParam.put("orderId", orderMap.get("id"));
            settleParam.put("outTradeNo", payOrderRelDO.getOutTradeNo());
//            settleParam.put("ruleId", orderMap.get("opxRuleId"));
            settleParam.put("totalAmount", payInfoDO.getPayCur());
            //收银台ID
            settleParam.put("counterId", counterId);
            //用户ID
            settleParam.put("customerId", orderMap.get("customerId"));
            //支付分账
            settleParam.put("settleType", "0");
            settleParam.put("payType", payInfoDO.getPayType());
            settleParam.put("payChannel", payInfoDO.getPayChannel());

            sendMQMessage(logBuilder.toString(), orderParam, settleParam,
                    PayMQConfig.ORDER_COMMODITY_TAG_PAY,PayMQConfig.SETTLE_TAG_SPLIT);
            return true;
        } else {
            LOGGER.info("{}不是商品订单发送订单、分账",baseLog);
            //获取订单信息
            Map orderMap = orderFeign.getOrderForPay(payOrderRelDO.getOrderId());

            if (orderMap == null) {
                LOGGER.error("{}订单中心返回参数为空",baseLog);
            }

            String orderId = orderMap.get("orderId")==null?null:orderMap.get("orderId").toString();

            if (orderId == null) {
                LOGGER.error("{}订单中心返回参数,订单号为空",baseLog);
            }

            //设置分账中心消息传递内容
            orderParam.put("orderId", orderId);

            //查询那个订单
            settleParam.put("orderId", orderId);
            settleParam.put("outTradeNo", payOrderRelDO.getOutTradeNo());
            settleParam.put("ruleId", orderMap.get("opxRuleId"));
            settleParam.put("totalAmount", payInfoDO.getPayCur());
            //收银台ID
            settleParam.put("counterId", orderMap.get("counterId"));
            //用户ID
            settleParam.put("customerId", orderMap.get("customerId"));
            //支付分账
            settleParam.put("settleType", "0");
            settleParam.put("payType", payInfoDO.getPayType());
            settleParam.put("payChannel", payInfoDO.getPayChannel());

            sendMQMessage(logBuilder.toString(), orderParam, settleParam,
                    PayMQConfig.ORDER_TAG_PAY,PayMQConfig.SETTLE_TAG_SPLIT);
        }

        return true;

    }

    /**
     * 积分回执发送订单、分账中心
     * @param pubLog 公共日志
     * @param orderParam    订单参数
     * @param settleParam   结算参数
     */
    private void sendMQMessage(String pubLog,Map<String, Object> orderParam,
                               Map<String, Object> settleParam,String orderTag,String settleTag) {
        try {
            Message orderMessage = new Message(PayMQConfig.ORDER_TOPIC, orderTag,
                    JSON.toJSONString(orderParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
            producer.send(orderMessage);
            LOGGER.info("发送订单中心成功,{}", pubLog);
        } catch (Exception e) {
            LOGGER.error("发送订单中心失败,{}", pubLog);
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //发送不成功的话，稍后重试
        }

//        if (!PayMQConfig.COMMODITY_SETTLE_TAG_SPLIT.equals(settleTag)) {
            try {
                //分账中心
                Message settleMessage = new Message(PayMQConfig.SETTLE_TOPIC, settleTag,
                        JSON.toJSONString(settleParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
                producer.send(settleMessage);
                LOGGER.info("发送分账中心成功,{}", pubLog);
            } catch (Exception e) {
                LOGGER.error("发送分账中心失败,{}", pubLog);
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                //发送不成功的话，稍后重试
//            }
        }
    }

}
